

package tomkitty;

import java.io.*;
import java.net.*;

public abstract class Turdlet implements Handler, HttpStatus, ConfigProperties {

  protected Handler handler;
  protected AppContext context;
  protected Request request;
  protected Response response;

  protected boolean finished = true;

  public abstract void doit();

  public Handler init(Handler handler, AppContext context) {
    this.handler = handler;
    this.context = context;

    return this;
  }

  public Handler getHandler() {
    return handler;
  }

  public void setHandler(Handler handler) {
    this.handler = handler;
  }

  public AppContext getContext() {
    return context;
  }

  public void setContext(AppContext context) {
    this.context = context;
    if (handler != null) {
      handler.setContext(context);
    }
  }

  public Handler clone() {
    Handler ret = null;
    try {
      ret = this.getClass().newInstance().init(
          (handler == null) ? null : handler.clone(), context);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return ret;
  }

  public void handle(Request req, Response resp) {
    this.request = req;
    this.response = resp;

    // HTTP_NOT_FOUND errors are okay, because various handlers will pass this
    // error until a handler can handle the request
    if (response.getStatus().equals(HTTP_OK) || 
        response.getStatus().equals(HTTP_NOT_FOUND)) {
      doit();

      while (! finished) {
        // spin
      }
    }

    // When a new thread is spawned to handle the request the handler who
    // spawns the thread should set the response to null, so that the
    // socket will not be closed prematurely, If headers have been sent
    // and the turdlet is finished working then we need to close the socket.
    // Otherwise we will pass the request on to the next handler and let
    // it close the socket.
    if (response != null && ! response.headerSent() && handler != null) {
      handler.handle(request, response);
    } else if (request != null && !request.getSocket().isClosed()) {
      try {
        request.getSocket().close();
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }

  protected void persist() {
    finished = false;
  }

  protected void done() {
    finished = true;
  }

  protected void println(String s) throws IOException {
    s = s + "\n";
    response.getSocket().getOutputStream().write(s.getBytes());
  }
}
